//  This file is part of Swordbible - http://www.swordwarrior.net
//  Copyright (C) 2003-2009 Manu Mital mital.manu@gmail.com

//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2, or (at your option)
//  any later version.

//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.

//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


// BibleSheet.cpp : implementation file
//

#include <stdafx.h>
#include "SwordBible.h"
#include "BibleSheet.h"
#include ".\biblesheet.h"
#include "SwordBibleView.h"


// CBibleSheet
CScriptureRef* CBibleSheet::pDlg;
HCURSOR CBibleSheet::m_hHandCursor; 
CString CBibleSheet::AppDirPrivate = _T("");
BOOL    CBibleSheet::AppDirPrivateExists = FALSE;


IMPLEMENT_DYNAMIC(CBibleSheet, CPropertySheet)
CBibleSheet::CBibleSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{

  

  title = nIDCaption;

	pMgr = NULL;pHTMLMgr = NULL;

  #if defined VERSION_PORTABLE
  CString path;
  GetAppDirectory(path);
  path.Replace(_T("\\App\\SwordBible"),  _T("\\Data\\"));
  pMgr = new sword::SWMgr( path, TRUE, new sword::MarkupFilterMgr(sword::FMT_RTF, sword::ENC_RTF));
	pHTMLMgr = new sword::SWMgr( path, TRUE, new sword::MarkupFilterMgr(sword::FMT_HTMLHREF,sword::ENC_HTML));
	
#else 

  pMgr = new sword::SWMgr(0, 0, TRUE, new sword::MarkupFilterMgr(sword::FMT_RTF, sword::ENC_RTF));
	pHTMLMgr = new sword::SWMgr(0,0, TRUE, new sword::MarkupFilterMgr(sword::FMT_HTMLHREF,sword::ENC_HTML));

  #endif

//  CString path = CSwordBibleDoc::driveLetter + _T(":\\Program Files\\CrossWire\\The SWORD Project\\");
//  pMgr->augmentModules((CStringA) path);
//  pHTMLMgr->augmentModules((CStringA) path);


	OnToggleTags(0,0); //turn on/off strong's, morphological tags
	pMgr->setGlobalOption("Greek Accents","Off");
	pMgr->setGlobalOption("Hebrew Cantillation","Off");
	pMgr->setGlobalOption("Hebrew Vowel Points","Off");

	pHTMLMgr->setGlobalOption("Greek Accents","Off");
	pHTMLMgr->setGlobalOption("Hebrew Cantillation","Off");
	pHTMLMgr->setGlobalOption("Hebrew Vowel Points","Off");
  pHTMLMgr->setGlobalOption("Morphological Tags", "Off");
	pHTMLMgr->setGlobalOption("Strong's Numbers", "Off");
	
	// finds modules installed on the system.
	sword::SWModule *pModule = NULL;  //pointer to a specific module
	sword::ModMap::iterator it;

	
	
	
	// Add pages to the top sheet
	if(nIDCaption == AFX_MAINBIBLE)
	{
      
	BiblePage = NULL;
	parallelPage = NULL;

	  // add the bible page
	   BiblePage = new CBiblePage();
	   AddPage(BiblePage);  
       BiblePage->m_psp.dwFlags |= PSP_USETITLE;
	   BiblePage->m_psp.pszTitle = _T("Bibles");

	   //add the compare page
	   comparePage = new CBibleCompare();
	   AddPage(comparePage);
	   comparePage->m_psp.dwFlags |= PSP_USETITLE;
	   comparePage->m_psp.pszTitle = _T("Compare");


	    // add the parallel page
	   parallelPage = new CParallelBible();
	   AddPage(parallelPage);  
       parallelPage->m_psp.dwFlags |= PSP_USETITLE;
	   parallelPage->m_psp.pszTitle = _T("Parallel");


	   CSwordBibleDoc::numBiblesAvailable = 0;

     for (it = pMgr->Modules.begin(); it != pMgr->Modules.end(); it++) {		
		
			pModule = it->second;

      if (!strcmp(pModule->Type(), "Biblical Texts") &&  CSwordBibleDoc::numBiblesAvailable < nBibles ) {
  	CSwordBibleDoc::pRTFBibleModule[CSwordBibleDoc::numBiblesAvailable++] = pModule;

      }

		}   // end of for loop


		int count = 0;
		for (it = pHTMLMgr->Modules.begin(); it != pHTMLMgr->Modules.end(); it++) {		
		
		pModule = it->second;

		if (!strcmp(pModule->Type(), "Biblical Texts") &&  count < nBibles )
		CSwordBibleDoc::pHTMLBibleModule[count++] = pModule;
		}   // end of for loop

	
      SetXrefActiveModule();//  Set the default module for displaying cross-references

	AfxGetMainWnd()->SendMessageToDescendants(WM_TREE_SETSEL,0,0,TRUE);
	
	} // done adding pages for the bibles


   // Add pages to the bottom sheet
	if(nIDCaption == AFX_BOTTOM)
	{

	// Add Page for the notes
	notes_page = NULL;
	notes_page = new CNotesPage(); 
	AddPage(notes_page);
	notes_page->m_psp.dwFlags |= PSP_USETITLE;
	notes_page->m_psp.pszTitle = _T("Notes");

	// Add Page for the  Commentaries
	BottomPage = NULL;
	BottomPage = new CBottomPage(); 
	AddPage(BottomPage);
	BottomPage->m_psp.dwFlags |= PSP_USETITLE;
	BottomPage->m_psp.pszTitle = _T("Commentaries");

	// Add the Page for GenBooks
	genbookPage = NULL;
	genbookPage = new CGenBooks(); 
	AddPage(genbookPage);
	genbookPage->m_psp.dwFlags |= PSP_USETITLE;
	genbookPage->m_psp.pszTitle = _T("Books");


	CSwordBibleDoc::numComAvailable = 0;
	CSwordBibleDoc::numGenBooksAvailable = 0;

	for (it = pMgr->Modules.begin(); it != pMgr->Modules.end(); it++) {
		
	pModule = it->second;
		
	if (!strcmp(pModule->Type(), "Commentaries") && CSwordBibleDoc::numComAvailable < nBottom)
		CSwordBibleDoc::pRTFComModule[CSwordBibleDoc::numComAvailable++] = pModule;

	else if(!strcmp(pModule->Type(), "Generic Books") && CSwordBibleDoc::numGenBooksAvailable < nGenBooks)     
		CSwordBibleDoc::pRTFGenBooks[CSwordBibleDoc::numGenBooksAvailable++] = pModule;
		

	}   // end of for loop 
	} // done adding pages for the bottom modules



   /************************ ADD PAGES FOR BOTTOM LEFT MODULES ***************************************/
	////////////////////////////////////////////////////////////////////////////////////////////////////
	CString isDevotion = _T("DailyDevotion");
	CString feature = _T("");
	
	if(nIDCaption == AFX_BOTTOMLEFT)
	{

	// Add Page for the dictionary
	BottomLeftPage = NULL;
	BottomLeftPage = new CBottomLeft(); 
	AddPage(BottomLeftPage);
	BottomLeftPage->m_psp.dwFlags |= PSP_USETITLE;
	BottomLeftPage->m_psp.pszTitle = _T("Lexicons / Dictionaries");

    CSwordBibleDoc::numDictAvailable = 0;

	for (it = pMgr->Modules.begin(); it != pMgr->Modules.end(); it++) {
		
	pModule = it->second;
	feature = pModule->getConfigEntry("Feature");
		
	 if ( (!strcmp(pModule->Type(), "Lexicons / Dictionaries"  )) && 
		 ( isDevotion.CompareNoCase(feature) != 0 ) && CSwordBibleDoc::numDictAvailable < nBottomLeft ) 
		CSwordBibleDoc::pRTFDictModule[CSwordBibleDoc::numDictAvailable++] = pModule;


	 } // end of the for loop

	// Add page for scripture reference
	 scripRefPage = NULL;
	 scripRefPage = new CScriptureRef();
	 pDlg = scripRefPage;
	 AddPage(scripRefPage);
	 scripRefPage->m_psp.dwFlags |= PSP_USETITLE |PSP_PREMATURE;
	 scripRefPage->m_psp.pszTitle = _T("Scripture Reference");

  SetDictActiveModule(); // set the default module for dictionary word lookups
  SetHebrewActiveModule(); // set the default module for displaying the hebrew references
  SetGreekActiveModule(); // set the default module for displaying the greek references
  SetMorphActiveModule(); // set the default module for displaying the morphological references

	} // done adding pages for the bottom left modules
	
	
	/************************ ADD PAGES FOR DEVOTIONAL MODULES ***************************************/
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if(nIDCaption == AFX_DEVOTIONAL)
	{
		
	CSwordBibleDoc::numDevAvailable = 0;

	for (it = pMgr->Modules.begin(); it != pMgr->Modules.end() && CSwordBibleDoc::numDevAvailable < nDevotional; it++) {
		
	pModule = it->second;
	CString feature = (CString) pModule->getConfigEntry("Feature");  
		
	if ( isDevotion.CompareNoCase(feature) == 0 )  
		CSwordBibleDoc::pRTFDevModule[CSwordBibleDoc::numDevAvailable++] = pModule;
		
	} // end of for loop


		// Add Page for the devotionals
		DevotionalPage = NULL;
		DevotionalPage = new CDevotionalPage(); 
		AddPage(DevotionalPage);
		DevotionalPage->m_psp.dwFlags |= PSP_USETITLE;
		DevotionalPage->m_psp.pszTitle = _T("Daily Devotionals");

      DBPage = NULL;
	    DBPage = new CDailyBiblePage;
      AddPage(DBPage);
	    DBPage->m_psp.dwFlags |= PSP_USETITLE;
	    DBPage->m_psp.pszTitle = _T(  "Daily Bible" );
		

	} // done adding pages for the devotionals and daily bible


}


/////////  Set the default module for displaying cross-references ////////////////////////////////////
void CBibleSheet::SetXrefActiveModule()
{

	CString name = AfxGetApp()->GetProfileString(_T("Tags"), _T("XrefModule"), _T("")); // name Xref module name from registry
	CSwordBibleDoc::pXrefModuleActive = pMgr->getModule((CStringA) name);    // static module pointer utilized for scripture references
	
	if(CSwordBibleDoc::pXrefModuleActive == NULL) 
			CSwordBibleDoc::pXrefModuleActive = CSwordBibleDoc::pRTFBibleModule[0];
	
}

void CBibleSheet::SetGreekActiveModule()
{
  CBiblePage::pGreek = NULL;
  CString name = AfxGetApp()->GetProfileString(_T("Tags"), _T("GreekModule"), _T("StrongsGreek")); // get greek module name from registry
	CBiblePage::pGreek = pMgr->getModule((CStringA) name);    // static module pointer utilized for greek references

	if(CBiblePage::pGreek == NULL) 
			CBiblePage::pGreek = CSwordBibleDoc::pRTFDictModule[0]; // pRTFDictModule[0] should be NULL if no dictionaries

}

void CBibleSheet::SetHebrewActiveModule()
{
  CBiblePage::pHebrew = NULL;
  CString name = AfxGetApp()->GetProfileString(_T("Tags"), _T("HebrewModule"), _T("StrongsHebrew")); // get Hebrew module name from registry
	CBiblePage::pHebrew = pMgr->getModule((CStringA) name);    // static module pointer utilized for hebrew references
   
  if(CBiblePage::pHebrew == NULL) 
			CBiblePage::pHebrew = CSwordBibleDoc::pRTFDictModule[0];    // pRTFDictModule[0] should be NULL if no dictionaries

}

/////////  Set the default module for dictionary lookups /////////////////////////
void CBibleSheet::SetDictActiveModule()
{
	CString name = AfxGetApp()->GetProfileString(_T("Tags"), _T("DictModule"), _T("")); // name Xref module name from registry
	CSwordBibleDoc::pDictModuleActive = pMgr->getModule((CStringA) name);    // static pointer for dictionary lookups
	
	if(CSwordBibleDoc::pDictModuleActive == NULL) 
			CSwordBibleDoc::pDictModuleActive = CSwordBibleDoc::pRTFDictModule[0];
	
}

/////////  Set the default module for morphological lookups /////////////////////////
void CBibleSheet::SetMorphActiveModule()
{
	CBiblePage::pMorph = NULL;
	CString name = AfxGetApp()->GetProfileString(_T("Tags"), _T("MorphModule"), _T("Robinson")); // name Xref module name from registry
	CBiblePage::pMorph = pMgr->getModule((CStringA) name);    // static pointer for dictionary lookups
	
	if(CBiblePage::pMorph == NULL) 
	 CBiblePage::pMorph = CSwordBibleDoc::pRTFDictModule[0];     // pRTFDictModule[0] should be NULL if no dictionaries
	
}



CBibleSheet::CBibleSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
	
}

CBibleSheet::~CBibleSheet()
{

	// if this property sheet instance is for the main bible pages, delete all pages it created
	if(title == AFX_MAINBIBLE) 
	{
		if(BiblePage) delete BiblePage;
		if(parallelPage) delete parallelPage;
		if(comparePage) delete comparePage;

		BiblePage = NULL;
		parallelPage = NULL;
		comparePage = NULL;
	}


	// if this property sheet instance is for the bottom pages, delete all bottom pages including notes property page
	else if (title == AFX_BOTTOM)
	{
        if( notes_page) delete  notes_page;
		if(BottomPage) delete BottomPage;
		if(genbookPage) delete genbookPage;

		notes_page = NULL;
		BottomPage = NULL;
		genbookPage = NULL;
	}


	// if this property sheet instance is for the bottom left pages, delete all pages it created
	else if(title == AFX_BOTTOMLEFT)
	{
	 if(BottomLeftPage) delete BottomLeftPage;
	BottomLeftPage = NULL;

	if( scripRefPage) delete  scripRefPage;
	scripRefPage = NULL;
	}




    // if this property sheet instance is for the devotional property pages, delete all pages it created
	else if(title == AFX_DEVOTIONAL)
	{
		if(DevotionalPage) delete DevotionalPage;

		if(DBPage) delete DBPage;
	
	}



		if (pMgr)
	{ delete pMgr ; pMgr  = NULL; }


    
	if (pHTMLMgr)
	{ delete pHTMLMgr ; pHTMLMgr  = NULL; }
	
	
}


LONG CBibleSheet::OnResizePage(UINT, LONG)
 {
	  // resize the page using m_PageRect which was set in ScaleSheet
     CPropertyPage* pPage = GetActivePage ();
     ASSERT (pPage);
     pPage->MoveWindow (&m_PageRect);

     return 0;
 }

void CBibleSheet::ScaleSheet(int Height, int Width)
{


	// resize the sheet
	 RECT rc;
     GetWindowRect (&rc);
   	 ScreenToClient (&rc);
     rc.right += Width ;
     rc.bottom += Height;
     MoveWindow (&rc);

	 // resize the CTabCtrl

     CTabCtrl* pTab = GetTabControl ();
     ASSERT (pTab);
     pTab->GetWindowRect (&rc);
     ScreenToClient (&rc);
     rc.right += Width ;
     rc.bottom += Height;
     pTab->MoveWindow (&rc);


	 // resize the page

     CPropertyPage* pPage = GetActivePage ();
     ASSERT (pPage);

     // store page size in m_PageRect
     pPage->GetWindowRect (&m_PageRect);
     ScreenToClient (&m_PageRect);

     m_PageRect.right += Width;
     m_PageRect.bottom += Height;
     pPage->MoveWindow (&m_PageRect);	
	 
	 
	
}


BEGIN_MESSAGE_MAP(CBibleSheet, CPropertySheet)

// manually added message map for resizing page
ON_MESSAGE (WM_RESIZEPAGE, OnResizePage)
ON_MESSAGE (WM_TOGGLE_TAGS, OnToggleTags)

ON_WM_DESTROY()
END_MESSAGE_MAP()


// CBibleSheet message handlers

BOOL CBibleSheet::OnInitDialog()
{
	BOOL bResult = CPropertySheet::OnInitDialog();

	// this will ensure that the left/right arrows show up if all tabs cannot fit in the view
	HWND hWnd = (HWND)::GetDlgItem(m_hWnd, AFX_IDC_TAB_CONTROL);
	if(::IsWindow(hWnd))
    CWnd::ModifyStyle(hWnd, TCS_MULTILINE, TCS_SINGLELINE, 0);

	// TODO:  Add your specialized code here
	// initialize m_pageRect and store page size in m_PageRect
		
	 CPropertyPage* pPage = NULL;
	 pPage = GetActivePage ();
 
	 if(pPage)
	 {

     pPage->GetWindowRect (&m_PageRect);
	 ScreenToClient(&m_PageRect);

	 SetActivePage(0);
	 }

    m_hHandCursor = AfxGetApp()->LoadCursor(IDC_CURSOR_HAND);

	

	return bResult;
}

BOOL CBibleSheet::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
	// TODO: Add your specialized code here and/or call the base class
	NMHDR* pnmh = (LPNMHDR) lParam;


	// the sheet resizes the page whenever it is activated
     // so we need to resize it to what we want
     if (TCN_SELCHANGE == pnmh->code)
         // user-defined message needs to be posted because page must
         // be resized after TCN_SELCHANGE has been processed
         PostMessage (WM_RESIZEPAGE);


	return CPropertySheet::OnNotify(wParam, lParam, pResult);
}

BOOL CBibleSheet::GetAppDirectory( CString& strAppDir )
{

  if( AppDirPrivateExists == TRUE)
  {
    strAppDir = AppDirPrivate;
    return TRUE;
  }


   DWORD dwSize     = _MAX_PATH + 1;
   LPTSTR pszAppDir = new TCHAR[dwSize];

   if( ::GetModuleFileName( NULL, pszAppDir, dwSize ) )
   {
      strAppDir = pszAppDir;
      int nPos = 0; 
	    nPos = strAppDir.ReverseFind(_T('\\'));
      if( -1 != nPos )
      {
         strAppDir = strAppDir.Left( nPos );
         AppDirPrivate = strAppDir;
         AppDirPrivateExists = TRUE;
      }
   }
   delete []pszAppDir;

   return AppDirPrivateExists;

}

BOOL CBibleSheet::PreTranslateMessage(MSG* pMsg)
{
	return CPropertySheet::PreTranslateMessage(pMsg);
}

LRESULT CBibleSheet::OnToggleTags(WPARAM, LPARAM)
{
	if(title != AFX_MAINBIBLE) return 0L;   // need to toggle tags only once. Not every instance of BibleSheet needs to do this


	if(CSwordBibleDoc::lemma_tags) pMgr->setGlobalOption("Strong's Numbers", "On");
	else pMgr->setGlobalOption("Strong's Numbers", "Off");

	if(CSwordBibleDoc::morph_tags) pMgr->setGlobalOption("Morphological Tags","On");
	else pMgr->setGlobalOption("Morphological Tags","Off");

	if(CSwordBibleDoc::fn_tags) pMgr->setGlobalOption("Footnotes","On");	
	else pMgr->setGlobalOption("Footnotes","Off");

	if(CSwordBibleDoc::crossref_tags) pMgr->setGlobalOption("Cross-references", "On");	
	else pMgr->setGlobalOption("Cross-references","Off");

	if(CSwordBibleDoc::heading_tags) pMgr->setGlobalOption("Headings","On");
	else pMgr->setGlobalOption("Headings","Off");

    if(CSwordBibleDoc::redchrist_tags) pMgr->setGlobalOption("Words of Christ in Red","On");
	else pMgr->setGlobalOption("Words of Christ in Red","Off");
	
  pHTMLMgr->setGlobalOption("Footnotes", pMgr->getGlobalOption("Footnotes"));
	pHTMLMgr->setGlobalOption("Cross-references", pMgr->getGlobalOption("Cross-references"));
	pHTMLMgr->setGlobalOption("Headings", pMgr->getGlobalOption("Headings"));
	pHTMLMgr->setGlobalOption("Words of Christ in Red", pMgr->getGlobalOption("Words of Christ in Red"));

	return 0L;
}

void CBibleSheet::DisplayReference(CString title, CString body)
{
	if(pDlg->GetSafeHwnd() == NULL) {
		return;
	}
	
	 TC_ITEM tcItem;
     tcItem.mask = TCIF_TEXT;
     tcItem.pszText = (LPTSTR)((LPCTSTR) title);
	 ((CBibleSheet*) pDlg->GetParent())->GetTabControl()->SetItem(1, &tcItem );
	
	// Display the reference
    pDlg->SetText(body);
	
			 
}

void CBibleSheet::OnDestroy()
{
	CPropertySheet::OnDestroy();
}

